﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents; 
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ComponentModel;
using System.Collections.ObjectModel;

using PhoneApp1;

namespace PivotApp1
{

    public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
    {
        
        private static double DEFAULT_BPM = 120;
        private static int DEFAULT_BLOCK_COUNT = 15;
        public static bool[,] chordsmatrix;
        public static int numrows = 4;
        public static int numcolumns = 15;
        public static string username = "";
        public static int userlevel = 1;

        private TremoloDataContext TremoloDB;

        // Define an observable collection property that controls can bind to.
        public ObservableCollection<UserTable> _tremoloItems;
        public ObservableCollection<UserTable> TremoloItems
        {
            get
            {
                return _tremoloItems;
            }
            set
            {
                if (_tremoloItems != value)
                {
                    _tremoloItems = value;
                    NotifyPropertyChanged("TremoloItems");
                }
            }
        }


        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // Set the data context of the listbox control to the sample data
            DataContext = App.ViewModel;
            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

            // Connect to the database and instantiate data context.
            TremoloDB = new TremoloDataContext(TremoloDataContext.DBConnectionString);
            var allUsers = from UserTable ra in TremoloDB.TremoloUserTable select ra;
            TremoloItems = new ObservableCollection<UserTable>(allUsers);
            
            
           
            SongListBox.ItemsSource = TremoloItems;

            // Data context and observable collection are children of the main page.
            this.DataContext = this;
            chordsmatrix = new bool[numcolumns, numrows];
        }
        
       

        // Load data for the ViewModel Items
        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (!App.ViewModel.IsDataLoaded)
            {
                App.ViewModel.LoadData();
            }
        }

        private void Button_Click_Save(object sender, RoutedEventArgs e)
        {

           // UserTable newClient = new UserTable { UserLevel = 0, UserName = "029" };

           // SongTable newsong = new SongTable { };
           
           // int i = 0;
           // while (i < numcolumns) {

           //     ChordTable c = new ChordTable { };
           //     TremoloDB.TremoloChordTable.InsertOnSubmit(c);

           // }
           // TremoloDB.SubmitChanges();
           // // TODO
           // // tähän toteutus tallennustapahtumasta
           // //SongTable uusi = new SongTable { SongName = "test",  };
           //// TremoloItems.Add(uusi);
           //// TremoloDB.TremoloSongTable.InsertOnSubmit(uusi);
           //// TremoloDB.SubmitChanges();
        }


        private void Button_Click_Open(object sender, RoutedEventArgs e)
        {
            // Todo
            // Toteutus tiedoston avaamisesta tai vaihtoehoisesti siirrytään biisilistaan ja sieltä valitaan biisi
            //var a = from SongTable t in TremoloDB.TremoloSongTable select t;
            //var query = from SongTable ra in TremoloDB.TremoloSongTable select ra;
           
            //List<SongTable> lista = query.ToList();
            //MessageBox.Show(lista.Count().ToString());
         
            //foreach (SongTable t in lista)
            //{
            //    MessageBox.Show(t.SongName);
                
            //}
            
        }

        private void Button_Click_Stop(object sender, System.Windows.RoutedEventArgs e)
        {
            
            SongListBox.UpdateLayout();
       //     MessageBox.Show(TremoloDB.TremoloUserTable.ToList().Count.ToString());
            
            Page1.stopTimer();
        }

        //private void button_Click_Start(object sender, RoutedEventArgs e)
        //{
        //    Page1.stopTimer();
        //    try
        //    {

        //        NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));

        //    }
        //    catch (NullReferenceException)
        //    {
        //        MessageBox.Show("Can't play.");
        //    }
        //}

        private void Button_Click_SettingsPage(object sender, RoutedEventArgs e)
        {
            Page1.stopTimer();
            if(userlevel == 0)
            {
                try
                {

                    NavigationService.Navigate(new Uri("/SettingsWithoutConfirmation.xaml", UriKind.Relative));

                }
                catch (NullReferenceException)
                {
                    MessageBox.Show("It seems that some error has occurred while loading page SWC");
                }
            }
        }

        private void button_Click_Login(object sender, RoutedEventArgs e)
        {
            Page1.stopTimer();
            try
            {

                NavigationService.Navigate(new Uri("/SettingsWithConfirmation.xaml", UriKind.Relative));

            }
            catch (NullReferenceException)
            {
                MessageBox.Show("It seems that some error has occurred loadin page SWOC");
            }
        }

        private void newUser(string name, int ulevel)
        {
            UserTable newuser = new UserTable { UserName = name,UserLevel = ulevel };
            TremoloDB.TremoloUserTable.InsertOnSubmit(newuser);
            TremoloDB.SubmitChanges();

        }

        private void newEvent(int uid, string name )
        {
            
            EventTable newevent = new EventTable { EventName = name, UserId=uid, Completion=49,EventDate=DateTime.Today};
            TremoloDB.TremoloEventTable.InsertOnSubmit(newevent);
            TremoloDB.SubmitChanges();

        }

        




        private void button_Click_Start(object sender, RoutedEventArgs e)
        {
            Page1.stopTimer();
            try
            {

                NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));

            }
            catch (NullReferenceException)
            {
                MessageBox.Show("Can't play.");
            }
        }


        private void Button_Click_Clear(object sender, RoutedEventArgs e)
        {
            // Todo: 
            // Toteutus taulukon tyhjentämisestä
            chordsmatrix = new bool[numcolumns, numrows];
            Button_Click_Stop(null,null);
          
            
        }

        private void button_Click_Events(object sender, RoutedEventArgs e)
        {
            Page1.stopTimer();
            if (username != "")
            {
                try
                {

                    NavigationService.Navigate(new Uri("/EventListView.xaml", UriKind.Relative));

                }
                catch (NullReferenceException)
                {
                    MessageBox.Show("Can't play.");
                }
            }
        }




        private void savebutton_advanced_Click(object sender, RoutedEventArgs e)
        {
            if (numcolumns > int.Parse(blockcounttext.Text))
            {
                double bpm = double.Parse(bpmtext.Text);
                Page1.BPM(60000 / bpm);
                numcolumns = int.Parse(blockcounttext.Text);
                
            }
            
        }

        private void defaultbutton_advanced_Click(object sender, RoutedEventArgs e)
        {
            Page1.BPM(60000 / DEFAULT_BPM);
            numcolumns = DEFAULT_BLOCK_COUNT;
            bpmslider.Value = DEFAULT_BPM;
        }

        private void bpmslider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Slider s = sender as Slider;
            if (bpmtext != null)
            {
                bpmtext.Text = Convert.ToInt32(s.Value).ToString();
            }
        }

       

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        // Used to notify Silverlight that a property has changed.
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        private void SongListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            UserTable data = (sender as ListBox).SelectedItem as UserTable;
            
            this.TremoloItems.Remove(data);
            
        }
                
    }

   

[Table]
public class SongTable : INotifyPropertyChanged, INotifyPropertyChanging
{
    // Define ID: private field, public property and database column.
    private int _tremoloSongId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int TremoloSongId
    {
        get
        {
            return _tremoloSongId;
        }
        set
        {
            if (_tremoloSongId != value)
            {
                NotifyPropertyChanging("songId");
                _tremoloSongId = value;
                NotifyPropertyChanged("songId");
            }
        }
    }

    // Define item name: private field, public property and database column.
    private string _songName;

    [Column]
    public string SongName
    {
        get
        {
            return _songName;
        }
        set
        {
            if (_songName != value)
            {
                NotifyPropertyChanging("SongName");
                _songName = value;
                NotifyPropertyChanged("SongName");
            }
        }
    }

    private string _creator;

    [Column]
    public string CreatorName
    {
        get
        {
            return _creator;
        }
        set
        {
            if (_creator != value)
            {
                NotifyPropertyChanging("CreatorName");
                _creator = value;
                NotifyPropertyChanged("CreatorName");
            }
        }
    }

    private DateTime _date;

    [Column]
    public DateTime SongDate
    {
        get
        {
            return _date;
        }
        set
        {
            if (_date != value)
            {
                NotifyPropertyChanging("SongDate");
                _date = value;
                NotifyPropertyChanged("SongDate");
            }
        }
    }

    private int _bpm;

    [Column]
    public int BPM
    {
        get
        {
            return _bpm;
        }
        set
        {
            if (_bpm != value)
            {
                NotifyPropertyChanging("BPM");
                _bpm = value;
                NotifyPropertyChanged("BPM");
            }
        }
    }

    private int _numcols;

    [Column]
    public int NumCols
    {
        get
        {
            return _numcols;
        }
        set
        {
            if (_numcols != value)
            {
                NotifyPropertyChanging("NumCols");
                _numcols = value;
                NotifyPropertyChanged("NumCols");
            }
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public string getSongName()
    {
        return SongName;
    }

    #endregion

    #region INotifyPropertyChanging Members

    public event PropertyChangingEventHandler PropertyChanging;

    // Used to notify the data context that a data context property is about to change
    private void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    #endregion
}


[Table]
public class UserTable : INotifyPropertyChanged, INotifyPropertyChanging
{
    // Define ID: private field, public property and database column.
    // Define ID: private field, public property and database column.
    private int _userId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int UserId
    {
        get
        {
            return _userId;
        }
        set
        {
            if (_userId != value)
            {
                NotifyPropertyChanging("UserId");
                _userId = value;
                NotifyPropertyChanged("UserId");
            }
        }
    }

    // Define item name: private field, public property and database column.
    private string _userName;

    [Column]
    public string UserName
    {
        get
        {
            return _userName;
        }
        set
        {
            if (_userName != value)
            {
                NotifyPropertyChanging("UserName");
                _userName = value;
                NotifyPropertyChanged("UserName");
            }
        }
    }

    private string _userPassword;

    [Column]
    public string UserPassword
    {
        get
        {
            return _userPassword;
        }
        set
        {
            if (_userPassword != value)
            {
                NotifyPropertyChanging("UserPassword");
                _userPassword = value;
                NotifyPropertyChanged("UserPassword");
            }
        }
    }

    private int _userLevel;

    [Column]
    public int UserLevel
    {
        get
        {
            return _userLevel;
        }
        set
        {
            if (_userLevel != value)
            {
                NotifyPropertyChanging("UserLevel");
                _userLevel = value;
                NotifyPropertyChanged("UserLevel");
            }
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    #endregion

    #region INotifyPropertyChanging Members

    public event PropertyChangingEventHandler PropertyChanging;

    // Used to notify the data context that a data context property is about to change
    private void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    #endregion
}

[Table]
public class EventTable : INotifyPropertyChanged, INotifyPropertyChanging
{
    // Define ID: private field, public property and database column.
    // Define ID: private field, public property and database column.
    private int _eventId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int EventId
    {
        get
        {
            return _eventId;
        }
        set
        {
            if (_eventId != value)
            {
                NotifyPropertyChanging("EventId");
                _eventId = value;
                NotifyPropertyChanged("EventId");
            }
        }
    }

    // Define item name: private field, public property and database column.
    private string _eventName;

    [Column]
    public string EventName
    {
        get
        {
            return _eventName;
        }
        set
        {
            if (_eventName != value)
            {
                NotifyPropertyChanging("EventName");
                _eventName = value;
                NotifyPropertyChanged("EventName");
            }
        }
    }

    private int _userId;

    [Column]
    public int UserId
    {
        get
        {
            return _userId;
        }
        set
        {
            if (_userId != value)
            {
                NotifyPropertyChanging("EventUserId");
                _userId = value;
                NotifyPropertyChanged("EventUserId");
            }
        }
    }

    private int _completion;

    [Column]
    public int Completion
    {
        get
        {
            return _completion;
        }
        set
        {
            if (_completion != value)
            {
                NotifyPropertyChanging("Completion");
                _completion = value;
                NotifyPropertyChanged("Completion");
            }
        }
    }

    private DateTime _date; 

    [Column]
    public DateTime EventDate
    {
        get
        {
            return _date;
        }
        set
        {
            if (_date != value)
            {
                NotifyPropertyChanging("EventDate");
                _date = value;
                NotifyPropertyChanged("EventDate");
            }
        }
    }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    #endregion

    #region INotifyPropertyChanging Members

    public event PropertyChangingEventHandler PropertyChanging;

    // Used to notify the data context that a data context property is about to change
    private void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    #endregion
}

[Table]
public class ChordTable : INotifyPropertyChanged, INotifyPropertyChanging
{
    // Define ID: private field, public property and database column.
    // Define ID: private field, public property and database column.
    private int _chordId;

    [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
    public int ChordId
    {
        get
        {
            return _chordId;
        }
        set
        {
            if (_chordId != value)
            {
                NotifyPropertyChanging("ChordId");
                _chordId = value;
                NotifyPropertyChanged("ChordId");
            }
        }
    }

    // Define item name: private field, public property and database column.
    

    private int _songId;

    [Column]
    public int SongId
    {
        get
        {
            return _songId;
        }
        set
        {
            if (_songId != value)
            {
                NotifyPropertyChanging("ChordSongId");
                _songId = value;
                NotifyPropertyChanged("ChordSongId");
            }
        }
    }

    private int _row;

    [Column]
    public int Row
    {
        get
        {
            return _row;
        }
        set
        {
            if (_row != value)
            {
                NotifyPropertyChanging("Row");
                _row = value;
                NotifyPropertyChanged("Row");
            }
        }
    }

    private int _col;

    [Column]
    public int Col
    {
        get
        {
            return _col;
        }
        set
        {
            if (_col != value)
            {
                NotifyPropertyChanging("Col");
                _col = value;
                NotifyPropertyChanged("Col");
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    // Used to notify the page that a data context property changed
    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }


    #endregion

    #region INotifyPropertyChanging Members

    public event PropertyChangingEventHandler PropertyChanging;

    // Used to notify the data context that a data context property is about to change
    private void NotifyPropertyChanging(string propertyName)
    {
        if (PropertyChanging != null)
        {
            PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
        }
    }

    #endregion
}


public class TremoloDataContext : DataContext
{
    // Specify the connection string as a static, used in main page and app.xaml.
    public static string DBConnectionString = "Data Source=isostore:/TremoloDB2.sdf";

    // Pass the connection string to the base class.
    public TremoloDataContext(string connectionString)
        : base(connectionString)
    { }

    // Specify a single table for the to-do items.
    public Table<SongTable> TremoloSongTable;
    public Table<UserTable> TremoloUserTable;
    public Table<ChordTable> TremoloChordTable;
    public Table<EventTable> TremoloEventTable;
}
}